package ocg.common.re.read;

import ocg.common.re.value.ObjectValue;
import ocg.common.re.value.ValueFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dom4j.Element;


import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by chenbo on 2018/3/14.
 */
public class XmlAssign {

    static Logger logger = LogManager.getLogger ( XmlAssign.class );

    /**
     * 返回 以 xml node 节点中 text() 为 key ,  Class<?> clazz 为 value 的  Map<String,Object> 数据
     * 如：<locator name="用户名" value="#accountTxt" outtime="3" type="css">username</locator>
     *      返回 ：{ username = clazz } , clazz 中 赋值 locator 节点的对于属性值
     *      clazz 的成员变量 必须和 locator 节点的属性值 数量、名称、大小写一一对应
     *      查询的节点名称，需要与实体类 clazz 名称相同
     * @param clazz
     * @param resourcePath
     * @return
     */
    public static Map<String,Object> assign( Class<?> clazz , String resourcePath ) throws ClassNotFoundException, IllegalAccessException, InstantiationException {

        Map<String,Object> map = new HashMap<String,Object> ();

        map.clear ();

        logger.info ( clazz.getClass () );

        logger.info ( "xml 路径 :" + resourcePath );

        XmlRead xmlRead = new XmlRead( );

        xmlRead.Xml ( resourcePath );

        String node = clazz.getSimpleName ().toLowerCase ();

        List<Element> elements = xmlRead.getNodes ( node );

        logger.info ( "读取 XML 文件中的节点：" + node );

        if ( elements.size () > 0 ){

            for(Element e : elements){
                Object obj = null ;

                Class clzss = Class.forName ( clazz.getName () );

//                获取类对象中 所以成员变量，不限制权限
                Field[] field = clzss.getDeclaredFields ();

                obj =  clzss.newInstance ();

                Map<String,String> AttributeMap = xmlRead.getAttribute ( e );

                for ( Field f : field ) {
//                  ObjectValue 接口，通过 locator 成员变量数据类型返回响应的类对象 ，反射
                    ObjectValue valueType = ValueFactory.getValues ( f.getType () );

                    String sim = AttributeMap.get ( f.getName () );
//                  数据类型转换
                    Object o = valueType.getValue ( sim );

//                  允许对私有成员赋值
                    f.setAccessible ( true );
//                  对 locator 成员变量赋值 ， 对于数据类型
                    f.set ( obj , o );
                }
                map.put ( e.getText () , obj );
            }

        } else {
            logger.error ( "获取节点数据失败，或节点不存在！ " + node );
        }

        if ( xmlRead != null ) {
            xmlRead.Cloes ();
            logger.info ( "清理资源" + resourcePath );
        }

        return map;
    }

    public static Map<String,Object> assign( Class<?> clazz , List<Element> list ){

        Map<String,Object> map = new HashMap<String,Object> ();

        map.clear ();

        if ( list.size () > 0 ){

            for(Element e : list){

                Object obj = null ;

                Class clzss = null;
                try {
                    clzss = Class.forName ( clazz.getName () );

                } catch (ClassNotFoundException e1) {
                    e1.printStackTrace ();
                }

//                获取类对象中 所以成员变量，不限制权限
                Field[] field = clzss.getDeclaredFields ();

                try {

                    obj =  clzss.newInstance ();


                } catch (InstantiationException e1) {
                    e1.printStackTrace ();
                } catch (IllegalAccessException e1) {
                    e1.printStackTrace ();
                }

                XmlRead xmlRead = new XmlRead (  );

                Map<String,String> Map = xmlRead.getAttribute ( e );

                for ( Field f : field ) {
//                  ObjectValue 接口，通过 locator 成员变量数据类型返回响应的类对象 ，反射
                    ObjectValue valueType = ValueFactory.getValues ( f.getType () );

                    String sim = Map.get ( f.getName () );
//                  数据类型转换
                    Object ov = valueType.getValue ( sim );

//                  允许对私有成员赋值
                    f.setAccessible ( true );
//                  对 locator 成员变量赋值 ， 对于数据类型
                    try {

                        f.set ( obj , ov );

                    } catch (IllegalAccessException e1) {
                        e1.printStackTrace ();
                    }
                }
                map.put ( e.getText () , obj );
            }

        } else {
            logger.error ( "获取节点数据失败，或节点不存在！ " + list );
        }

        return map;
    }
}
